// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: basic_log_factory.hpp 216 2008-09-03 08:13:29Z heavyzheng $
//

#ifndef ZZHENG_LOGGING_BASIC_LOG_FACTORY_HPP_20080901__
#define ZZHENG_LOGGING_BASIC_LOG_FACTORY_HPP_20080901__

#include <zzheng/logging/config.hpp>
#include <zzheng/logging/log_level.hpp>
#include <zzheng/logging/destination.hpp>
#include <zzheng/logging/basic_logger.hpp>

#include <boost/noncopyable.hpp>
#include <cassert>
#include <string>

namespace zzheng {
namespace logging {

    template<class Factory>
    class basic_log_factory: private boost::noncopyable {

        typedef basic_log_factory<Factory> this_type;
        typedef Factory                    impl_type;
        typedef basic_logger<Factory>      logger_type;

    public:

        //! Returns the singleton log factory instance.
        //! \return the singleton log factory instance.
        static this_type& instance() {
            static this_type instance;
            return instance;
        }

        //! Sets the default threshold to the log factory. The default threshold will not take
        //! effect until configure() is called.
        //! \param threshold  the default threshold to set.
        void set_threshold(const log_level& threshold) {
            impl().set_threshold(threshold);
        }

        //! Adds a logging destination to the log factory. The new logging destination will not
        //! take effect until configure() is called.
        //! \param name  the name of the logging destination.
        //! \param dest  the logging destination.
        void add_destination(const std::string& name, const destination& dest) {
            impl().add_destination(name, dest);
        }

        //! Configures the log factory.
        //! \return true if the log factory is configured successfully, false otherwise.
        bool configure() {
            return impl().configure();
        }

        //! Returns the reference to the root logger.
        //! \return the reference to the root logger.
        logger_type get_root() {
            return logger_type(impl().get_root());
        }

        //! Returns a named logger. If the logger exists in this factory, it is returned by copy.
        //! If it does not yet exists in this factory, it is firstly created, and registered into
        //! this factory, and then returned by copy.
        //! \param name  the name of the logger.
        //! \return the named logger.
        // boost::weak_ptr<logger> get_logger(const std::string& name)

    private:

        explicit basic_log_factory() {
            impl_type::instance(); // make sure the underlying log factory singleton is created.
        }

        ~basic_log_factory() {
            // Do nothing.
        }

        const impl_type& impl() const {
            return impl_type::instance();
        }

        impl_type& impl() {
            return impl_type::instance();
        }

    }; // class basic_log_factory<Factory>

} // namespace zzheng::logging
} // namespace zzheng

#endif // ZZHENG_LOGGING_BASIC_LOG_FACTORY_HPP_20080901__



